﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;


namespace CustomForms
{
    [RunInstaller(true)]
    public partial class InstallMembership : System.Configuration.Install.Installer
    {
        const string DESTDIR = "ddir";

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

        public static extern int GetShortPathName(

                 [MarshalAs(UnmanagedType.LPTStr)]

                   string path,

                 [MarshalAs(UnmanagedType.LPTStr)]

                   StringBuilder shortPath,

                    int shortPathLength

                 );

        
        public InstallMembership()
        {
            InitializeComponent();
        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);

            MembershipDetails msDetails = new MembershipDetails();
            msDetails.ShowDialog();

            string destPath = Context.Parameters[DESTDIR].ToString();

            //ExecuteProcess(String.Empty, "PowerShell.exe", "set-executionpolicy -scope CurrentUser -executionPolicy remotesigned");
            StringBuilder shortPath = new StringBuilder(255);
            GetShortPathName(destPath, shortPath, shortPath.Capacity);
            ExecuteProcess(String.Empty, "PowerShell.exe", shortPath.ToString());

            try
            {
                bool isMembershipDBSuccessfulCreated = false;
                string connectionStringValue = RunMembershipInstaller(msDetails.IsWindowsCredentials, msDetails.DatabaseServer, msDetails.DatabaseName, msDetails.UserName, msDetails.Password, out isMembershipDBSuccessfulCreated);

                string destValueTmp = @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG";
                string stsConfig = @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken";
                string centralAdminConfigPath = @"C:\inetpub\wwwroot\wss\VirtualDirectories\26500";
                if (isMembershipDBSuccessfulCreated)
                {
                    SupplementalWebConfigManager.CreateSupplementalConfig(connectionStringValue, destValueTmp);
                    SupplementalWebConfigManager.ModifySTSWebConfig(connectionStringValue, stsConfig);
                    SupplementalWebConfigManager.ModifyCentralAdminConfig(connectionStringValue, centralAdminConfigPath);
                }
                else
                {
                    //rollback the installation
                    throw new Exception("Memership database was not created successful. Current installation will be rolled back.");
                }
            }
            catch (Exception ex)
            {
                //TODO: write in event logs, etc...
                throw ex;
                
            }

        }

        private static void ExecuteProcess(string folderName, string command, string arguments)
        {

            // Start the child process.
            Process p = new Process();
            // Redirect the output stream of the child process.
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = command;
            p.StartInfo.Arguments = arguments;
            p.Start();
           
            // Read the output stream first and then wait.
            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();

            

        }

        private static bool AspNetRegSqlExecuteProcess(string folderName, string command, string arguments)
        {
            bool operationResult = false;

            // Start the child process.
            Process p = new Process();
            // Redirect the output stream of the child process.
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = command;
            p.StartInfo.Arguments = arguments;
            p.Start();
            
            string output = p.StandardOutput.ReadToEnd();
            output = output.TrimEnd('\n', '\t', ' ', '\r');
            if (output.EndsWith("Finished."))
            {
                operationResult = true;
            }
            p.WaitForExit();

            return operationResult;

        }

        private static string RunMembershipInstaller(bool isWindowsAccountUsed, string servername, string databsename, string username, string password, out bool result)
        {
            
            if (String.IsNullOrEmpty(servername) )
                throw new ArgumentNullException(servername);

            if (String.IsNullOrEmpty(databsename))
                throw new ArgumentNullException(databsename);

            string connectionString = String.Empty;
            string aspnet_regsqlPath = GetPathToAspnet_regsql();
            if (isWindowsAccountUsed)
            {

               string attributes = String.Format(" -A all -E -S {0} -d {1}", servername, databsename);
               string command = String.Concat("&", " ", aspnet_regsqlPath, attributes);
               result = AspNetRegSqlExecuteProcess(String.Empty, "PowerShell.exe", command);
               connectionString = String.Format("Data Source={0}; Integrated Security=True; Database={1}", servername,databsename);
            }
            else
            {

                if (String.IsNullOrEmpty(username) )
                    throw new ArgumentNullException(username);
                if (String.IsNullOrEmpty(password) )
                    throw new ArgumentNullException(password);

                string attributes = String.Format(" -S {0} -U {1} -P {2} -d {3} -A all", servername, username, password, databsename);
                string command = String.Concat("&", " ", aspnet_regsqlPath, attributes);

                result = AspNetRegSqlExecuteProcess(String.Empty, "PowerShell.exe", command);
                connectionString = String.Format("Data Source={0}; Integrated Security=false; Database={1};User ID={2};Password={3};", servername, databsename, username, password);

            }

            return connectionString;
        }

        private static string GetPathToAspnet_regsql()
        {
            string path = String.Empty;
            string windirPath = Environment.GetEnvironmentVariable("windir");
            path = System.IO.Path.Combine(windirPath, @"Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe");
            return String.Format("\"{0}\"",path);
        }
    }
}
